/**
 * @(#)ChatService.java 2013-11-27 Copyright 2013 it.kedacom.com, Inc. All
 *                      rights reserved.
 */

package com.kedacom.cometd;

/**
 * @author linfangfa
 * @date 2013-11-27
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.inject.Inject;

import net.sf.json.JSONObject;

import org.cometd.annotation.Configure;
import org.cometd.annotation.Listener;
import org.cometd.annotation.Service;
import org.cometd.annotation.Session;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ConfigurableServerChannel;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.authorizer.GrantAuthorizer;

@Service("chat")
public class ChatService {

	private final ConcurrentMap<String, Map<String, String>> _members = new ConcurrentHashMap<String, Map<String, String>>();
	@Inject
	private BayeuxServer _bayeux;
	@Session
	private ServerSession _session;

	@Configure("/notify/system")
	protected void configureNotify(ConfigurableServerChannel channel) {
		channel.addAuthorizer(GrantAuthorizer.GRANT_ALL);
	}

	@Configure("/service/members")
	protected void configureMembers(ConfigurableServerChannel channel) {
		channel.addAuthorizer(GrantAuthorizer.GRANT_PUBLISH);
		channel.setPersistent(true);
	}

	@Listener("/service/members")
	public void handleMembership(ServerSession client, ServerMessage message) {
		Map<String, Object> data = message.getDataAsMap();
		final String moid = (String) data.get("user");
		Map<String, String> userUUIDs = _members.get(moid);
		if (userUUIDs == null) {
			Map<String, String> new_UUID = new ConcurrentHashMap<String, String>();
			userUUIDs = _members.putIfAbsent(moid, new_UUID);
			if (userUUIDs == null) userUUIDs = new_UUID;
		}

		final Map<String, String> UUIDs = userUUIDs;
		String uid = (String) data.get("uuid");
		UUIDs.put(uid, client.getId());
		client.addListener(new ServerSession.RemoveListener() {

			public void removed(ServerSession session, boolean timeout) {
				UUIDs.values().remove(session.getId());
				_members.put(moid, UUIDs);

			}
		});

		System.out.println("所有客户端：" + JSONObject.fromObject(_members));
	}

	private void broadcastNotify(String moids, ServerMessage.Mutable forward) {
		String[] arr = moids.split(",");
		for (String s : arr) {
			List<ServerSession> list = this.getSessions(s);
			for (int i = 0; i < list.size(); i++) {
				ServerSession session = list.get(i);
				if (session != null) {
					try {
						session.deliver(_session, forward);

					} catch (Exception e) {

					}
				}
			}
		}
	}

	@Listener("/notify/system")
	protected void sysNotify(ServerSession client, ServerMessage message) {

		Map<String, Object> data = message.getDataAsMap();
		String receivers = (String) data.get("receivers");
		if (receivers != null && !"".equals(receivers)) {
			try {

				Map<String, Object> chat = new HashMap<String, Object>();

				chat.put("type", "notify");
				chat.put("message", "有一条新通知");
				ServerMessage.Mutable forward = _bayeux.newMessage();
				forward.setChannel("/notify/system");
				forward.setData(chat);

				this.broadcastNotify(receivers, forward);

			} catch (Exception e) {

			}
		}
	}

	private List<ServerSession> getSessions(String moid) {
		List<ServerSession> list = new ArrayList<ServerSession>();
		Map<String, String> uuidMap = _members.get(moid);
		if (uuidMap != null) {
			Set<String> key = uuidMap.keySet();
			for (Iterator<String> it = key.iterator(); it.hasNext();) {
				String s = (String) it.next();

				String clientid = uuidMap.get(s);

				ServerSession session = _bayeux.getSession(clientid);
				System.out.println(clientid + "--");
				if (session != null && !list.contains(session)) list.add(session);

			}
		}
		return list;
	}

}
